package com.fin.zw.aiqas.service;

import com.fin.zw.aiqas.entity.*;
import com.fin.zw.aiqas.enums.Synchronization;
import com.fin.zw.aiqas.model.request.ScenesRequest;
import com.fin.zw.aiqas.model.session.SessionModel;
import com.fin.zw.aiqas.repository.FormulaInfoRepository;
import com.fin.zw.aiqas.repository.RuleInfoRepository;
import com.fin.zw.aiqas.repository.ScenesRepository;
import com.fin.zw.aiqas.repository.TemplateInfoRepository;
import com.fin.zw.aiqas.util.BadRequestException;
import com.google.common.collect.Lists;
import com.querydsl.core.BooleanBuilder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;

@Service("scenesService")
public class ScenesService {

    @Autowired
    private ScenesRepository scenesRepository;
    @Autowired
    private RuleInfoRepository ruleInfoRepository;
    @Autowired
    private FormulaInfoRepository formulaInfoRepository;
    @Autowired
    private TemplateInfoRepository templateInfoRepository;
    private QScenesInfo qScenesInfo = QScenesInfo.scenesInfo;

    /**
     * 质检点分类查询（分页）
     *
     * @param pageable
     * @return
     */
    public Page<ScenesInfo> queryRuleScenes(ScenesRequest request, Pageable pageable) {
        BooleanBuilder builder = new BooleanBuilder();
        if (request.getId() != null)
            builder.and(qScenesInfo.id.eq(request.getId()));
        if (StringUtils.isNotBlank(request.getName()))
            builder.and(qScenesInfo.name.like("%" + request.getName() + "%"));
        if (StringUtils.isNotBlank(request.getScenesCode()))
            builder.and(qScenesInfo.scenesCode.eq(request.getScenesCode()));
        if (StringUtils.isNotBlank(request.getRemark()))
            builder.and(qScenesInfo.remark.like("%" + request.getRemark() + "%"));
        return scenesRepository.findAll(builder, pageable);
    }

    /**
     * 质检点分类查询
     *
     * @return
     */
    public List<ScenesInfo> queryRuleScenes(ScenesRequest request) {
        QScenesInfo qScenesInfo = QScenesInfo.scenesInfo;
        BooleanBuilder builder = new BooleanBuilder();
        if (request.getId() != null)
            builder.and(qScenesInfo.id.eq(request.getId()));
        if (StringUtils.isNotBlank(request.getName()))
            builder.and(qScenesInfo.name.like("%" + request.getName() + "%"));
        if (StringUtils.isNotBlank(request.getScenesCode()))
            builder.and(qScenesInfo.scenesCode.eq(request.getScenesCode()));
        if (StringUtils.isNotBlank(request.getRemark()))
            builder.and(qScenesInfo.remark.like("%" + request.getRemark() + "%"));
        return Lists.newArrayList(scenesRepository.findAll(builder));
    }

    /**
     * 质检点分类信息添加
     *
     * @param request
     * @param sessionModel
     */
    public void createScenes(ScenesRequest request, SessionModel sessionModel) {
        QScenesInfo qScenesInfo = QScenesInfo.scenesInfo;
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(qScenesInfo.scenesCode.eq(request.getScenesCode()));
        Iterator<ScenesInfo> iterator = scenesRepository.findAll(builder).iterator();
        if (iterator.hasNext()) {
            throw new BadRequestException("", request.getScenesCode()+"场景编号已经存在！");
        }
        builder = new BooleanBuilder();
        builder.and(qScenesInfo.name.eq(request.getName()));
        iterator = scenesRepository.findAll(builder).iterator();
        if (iterator.hasNext()) {
            throw new BadRequestException("", request.getName()+"场景名称已经存在！");
        }
        ScenesInfo scenesInfo = new ScenesInfo();
        BeanUtils.copyProperties(request, scenesInfo);
        scenesInfo.setCreateTime(new Date());
        scenesInfo.setIsSynchronize(Synchronization.NO);
        scenesInfo.setOperatorId(sessionModel.getUserId());
        scenesInfo.setOperatorRealName(sessionModel.getUserName());
        scenesRepository.save(scenesInfo);
    }

    /**
     * 质检点分类信息更新
     *
     * @param request
     * @param sessionModel
     */
    public void updateScenes(ScenesRequest request, SessionModel sessionModel) {

        Optional<ScenesInfo> optional = scenesRepository.findById(request.getId());
        if (!optional.isPresent()) {
            throw new BadRequestException("ruleClassify", "修改的规则分类信息不存在！");
        }
        BooleanBuilder builder = new BooleanBuilder();
        QScenesInfo qScenesInfo = QScenesInfo.scenesInfo;
        builder.and(qScenesInfo.scenesCode.eq(request.getScenesCode()));
        builder.and(qScenesInfo.id.ne(request.getId()));
        Iterator<ScenesInfo> iterator = scenesRepository.findAll(builder).iterator();
        if (iterator.hasNext()) {
            throw new BadRequestException("", request.getScenesCode()+"场景编号已经存在！");
        }
        BooleanBuilder builder1 = new BooleanBuilder();
        builder1.and(qScenesInfo.name.eq(request.getName()));
        builder1.and(qScenesInfo.id.ne(request.getId()));
        iterator = scenesRepository.findAll(builder1).iterator();
        if (iterator.hasNext()) {
            throw new BadRequestException("", request.getName()+"场景名称已经存在！");
        }
        ScenesInfo scenesInfo = optional.get();
        BeanUtils.copyProperties(request, scenesInfo);
        scenesInfo.setUpdateTime(new Date());
        scenesInfo.setUpdateUserId(sessionModel.getUserId());
        scenesInfo.setUpdateRealName(sessionModel.getUserName());
        scenesRepository.save(scenesInfo);
    }

    /**
     * 根据ID删除应用场景
     * @param scenesId
     */
    @Transactional
    public void deleteScenes(Long scenesId) {
        Iterable<RuleInfo> ruleInfos = ruleInfoRepository.findAll(QRuleInfo.ruleInfo.scenesInfo.id.eq(scenesId));
        if (ruleInfos.iterator().hasNext()) throw new BadRequestException("", "该场景在质检规则中有引用,无法删除!!!");
        Iterable<FormulaInfo> formuals = formulaInfoRepository.findAll(QFormulaInfo.formulaInfo.scenesInfo.id.eq(scenesId));
        if (formuals.iterator().hasNext()) throw new BadRequestException("", "该场景在质检质检点中有引用,无法删除!!!");
        Iterable<TemplateInfo> templateInfos = templateInfoRepository.findAll(QTemplateInfo.templateInfo.scenesInfo.id.eq(scenesId));
        if (templateInfos.iterator().hasNext()) throw new BadRequestException("", "该场景在样本中有引用,无法删除!!!");
        scenesRepository.deleteById(scenesId);
    }
}
